package handler

import (
	"api/common"
	"api/config"
	"api/internal/request"
	"api/pkg"
	"flag"
	"fmt"
	"github.com/dgrijalva/jwt-go"
	"github.com/gin-gonic/gin"
	"github.com/minio/minio-go/v7"
	"github.com/minio/minio-go/v7/pkg/credentials"
	"google.golang.org/grpc"
	"google.golang.org/grpc/credentials/insecure"
	"log"
	"mime"
	"net/http"
	"path/filepath"
	pb "srv/proto"
	"time"
)

var (
	addr = flag.String("addr", "localhost:50051", "the address to connect to")
)

// 用户注册登录一体化
func UserRegister(c *gin.Context) {
	json := request.UserRegisterRequest{}
	err := c.ShouldBindJSON(&json)
	if err != nil {
		c.JSON(http.StatusBadRequest, common.JsonRes{
			Message: "参数错误",
			Code:    500,
			Data:    nil,
		})
		return
	}
	flag.Parse()
	// Set up a connection to the server.
	conn, err := grpc.NewClient(*addr, grpc.WithTransportCredentials(insecure.NewCredentials()))
	if err != nil {
		log.Fatalf("did not connect: %v", err)
	}
	defer conn.Close()
	con := pb.NewUserClient(conn)
	r, err := con.UserRegister(c, &pb.UserRegisterReq{Username: json.Username, Password: json.Password})
	if err != nil {
		c.JSON(http.StatusBadRequest, common.JsonRes{
			Message: pkg.TrimPrefix(err.Error()),
			Code:    500,
			Data:    nil,
		})
		return
	}
	claims := pkg.CustomClaims{
		ID:             uint(r.Id),
		StandardClaims: jwt.StandardClaims{},
	}
	newJWT := pkg.NewJWT(config.DataConfig.Jwt.SecretKey)
	token, _ := newJWT.CreateToken(claims)
	c.JSON(http.StatusOK, common.JsonRes{
		Message: "注册或登录成功",
		Code:    200,
		Data:    token,
	})
}

// 视频上传minio
func Upload(c *gin.Context) {
	C := config.DataConfig.Minio
	file, err := c.FormFile("video")
	if err != nil {
		c.JSON(http.StatusBadRequest, common.JsonRes{
			Message: "视频读取失败",
			Code:    500,
			Data:    nil,
		})
		return
	}
	client, err := minio.New(C.Endpoint, &minio.Options{Creds: credentials.NewStaticV4(C.AccessKeyID, C.SecretAccessKey, "")})
	if err != nil {
		log.Fatalln(err)
	}
	open, _ := file.Open()
	location, _ := time.LoadLocation("Asia/Shanghai")
	format := time.Now().In(location).Format("20060102150405")
	ext := filepath.Ext(file.Filename)
	extension := mime.TypeByExtension(ext)
	if file.Size > 100*1024*1024 {
		c.JSON(http.StatusBadRequest, common.JsonRes{
			Message: "视频大小不能超过100MB",
			Code:    500,
			Data:    nil,
		})
		return
	}
	sprintf := fmt.Sprintf("%s/%s", format, file.Filename)
	client.PutObject(c, C.BucketName, sprintf, open, file.Size, minio.PutObjectOptions{ContentType: extension})
	url := fmt.Sprintf("http://%s/%s/%s", C.Endpoint, C.BucketName, sprintf)
	c.JSON(http.StatusOK, common.JsonRes{
		Message: "视频上传成功",
		Code:    200,
		Data:    url,
	})
}

// 视频发布
func VideoCreate(c *gin.Context) {
	value, _ := c.Get("userId")
	uid := value.(uint)
	json := request.VideoCreateRequest{}
	err := c.ShouldBindJSON(&json)
	if err != nil {
		c.JSON(http.StatusBadRequest, common.JsonRes{
			Message: "参数错误",
			Code:    500,
			Data:    nil,
		})
		return
	}
	flag.Parse()
	// Set up a connection to the server.
	conn, err := grpc.NewClient(*addr, grpc.WithTransportCredentials(insecure.NewCredentials()))
	if err != nil {
		log.Fatalf("did not connect: %v", err)
	}
	defer conn.Close()
	con := pb.NewUserClient(conn)
	r, err := con.VideoCreate(c, &pb.VideoCreateReq{
		UserId:           int64(uid),
		VideoUrl:         json.VideoUrl,
		VideoCover:       json.VideoCover,
		VideoStatus:      int64(json.VideoStatus),
		VideoAdoptStatus: int64(json.VideoAdoptStatus),
		Type:             int64(json.Type),
	})
	if err != nil {
		c.JSON(http.StatusBadRequest, common.JsonRes{
			Message: pkg.TrimPrefix(err.Error()),
			Code:    500,
			Data:    nil,
		})
		return
	}
	c.JSON(http.StatusOK, common.JsonRes{
		Message: "发布成功",
		Code:    200,
		Data:    r,
	})
}

// 视频列表
func VideoList(c *gin.Context) {
	json := request.VideoListRequest{}
	err := c.ShouldBindJSON(&json)
	if err != nil {
		c.JSON(http.StatusBadRequest, common.JsonRes{
			Message: "参数错误",
			Code:    500,
			Data:    nil,
		})
		return
	}
	flag.Parse()
	// Set up a connection to the server.
	conn, err := grpc.NewClient(*addr, grpc.WithTransportCredentials(insecure.NewCredentials()))
	if err != nil {
		log.Fatalf("did not connect: %v", err)
	}
	defer conn.Close()
	con := pb.NewUserClient(conn)
	r, err := con.VideoList(c, &pb.VideoListReq{
		Page: int64(json.Page),
		Size: int64(json.Size),
	})
	if err != nil {
		c.JSON(http.StatusBadRequest, common.JsonRes{
			Message: pkg.TrimPrefix(err.Error()),
			Code:    500,
			Data:    nil,
		})
		return
	}
	c.JSON(http.StatusOK, common.JsonRes{
		Message: "列表展示成功",
		Code:    200,
		Data:    r,
	})
}

// 个人主页
func UserShow(c *gin.Context) {
	json := request.UserShowRequest{}
	err := c.ShouldBindJSON(&json)
	if err != nil {
		c.JSON(http.StatusBadRequest, common.JsonRes{
			Message: "参数错误",
			Code:    500,
			Data:    nil,
		})
		return
	}
	flag.Parse()
	// Set up a connection to the server.
	conn, err := grpc.NewClient(*addr, grpc.WithTransportCredentials(insecure.NewCredentials()))
	if err != nil {
		log.Fatalf("did not connect: %v", err)
	}
	defer conn.Close()
	con := pb.NewUserClient(conn)
	r, err := con.UserShow(c, &pb.UserShowReq{
		Id: int64(json.Id),
	})
	if err != nil {
		c.JSON(http.StatusBadRequest, common.JsonRes{
			Message: pkg.TrimPrefix(err.Error()),
			Code:    500,
			Data:    nil,
		})
		return
	}
	c.JSON(http.StatusOK, common.JsonRes{
		Message: "个人主页展示成功",
		Code:    200,
		Data:    r,
	})
}
